package com.youlai.boot.modules.tp.service.impl;

import com.youlai.boot.modules.tp.dto.query.DateRangeQuery;
import com.youlai.boot.modules.tp.dto.response.*;
import com.youlai.boot.modules.tp.entity.DailySalesReport;
import com.youlai.boot.modules.tp.mapper.DailySalesReportMapper;
import com.youlai.boot.modules.tp.mapper.ProductSalesMapper;
import com.youlai.boot.modules.tp.service.TPDashboardService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * TP看板服务实现类
 * 
 * @author Jason
 * @since 2025-06-04
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TPDashboardServiceImpl implements TPDashboardService {

    @Qualifier("tpDailySalesReportMapper")
    private final DailySalesReportMapper dailySalesReportMapper;
    @Qualifier("tpProductSalesMapper")
    private final ProductSalesMapper productSalesMapper;
    
    private final Random random = new Random();
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("MM-dd");

    @Override
    public DashboardHeaderInfoVO getHeaderInfo() {
        try {
            // 获取最新销售报表数据
            DailySalesReport latestReport = dailySalesReportMapper.getLatestSalesReport();
            
            if (latestReport == null) {
                return createMockHeaderInfo();
            }
            
            // 获取当前月份的店铺数据
            String currentTimePeriod = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
            List<Map<String, Object>> shopData = productSalesMapper.getShopSalesData(currentTimePeriod);
            
            return DashboardHeaderInfoVO.builder()
                    .onlineUsers(generateOnlineUsers())
                    .onlineGrowth(BigDecimal.valueOf(8.5))
                    .salesProgress(latestReport.getSalesProgress())
                    .storeCount(shopData != null ? shopData.size() : 5)
                    .storeStatus("open")
                    .build();
        } catch (Exception e) {
            log.error("获取头部信息失败", e);
            return createMockHeaderInfo();
        }
    }

    @Override
    public KPIMetricsVO getKPIMetrics(DateRangeQuery queryParams) {
        try {
            LocalDate startDate = queryParams != null ? queryParams.getStartDate() : LocalDate.now();
            LocalDate endDate = queryParams != null ? queryParams.getEndDate() : LocalDate.now();
            LocalDate today = LocalDate.now();
            LocalDate yesterday = today.minusDays(1);
            
            // 获取今日指标
            Map<String, Object> todayMetrics = dailySalesReportMapper.getTodayMetrics(today);
            
            // 计算增长率
            Map<String, Object> growthRates = dailySalesReportMapper.calculateGrowthRates(today, yesterday);
            
            if (todayMetrics == null) {
                return createMockKPIMetrics();
            }
            
            BigDecimal todayGMV = (BigDecimal) todayMetrics.get("todayGMV");
            BigDecimal monthlyTarget = (BigDecimal) todayMetrics.get("monthly_sales_target");
            Integer todayOrders = (Integer) todayMetrics.get("todayOrders");
            BigDecimal conversionRate = (BigDecimal) todayMetrics.get("conversion_rate");
            BigDecimal salesProgress = (BigDecimal) todayMetrics.get("sales_progress");
            
            BigDecimal gmvGrowth = growthRates != null ? (BigDecimal) growthRates.get("gmvGrowth") : BigDecimal.ZERO;
            BigDecimal ordersGrowth = growthRates != null ? (BigDecimal) growthRates.get("ordersGrowth") : BigDecimal.ZERO;
            
            // 计算目标达成率
            BigDecimal targetAchievement = monthlyTarget != null && monthlyTarget.compareTo(BigDecimal.ZERO) > 0 
                    ? todayGMV.divide(monthlyTarget, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100))
                    : BigDecimal.ZERO;
            
            return KPIMetricsVO.builder()
                    .todayGMV(todayGMV != null ? todayGMV : BigDecimal.ZERO)
                    .gmvGrowth(gmvGrowth)
                    .targetAchievement(targetAchievement)
                    .targetGrowth(BigDecimal.valueOf(12.8))
                    .monthlyTarget(monthlyTarget != null ? monthlyTarget : BigDecimal.ZERO)
                    .todayOrders(todayOrders != null ? todayOrders : 0)
                    .yesterdayOrders(todayOrders != null ? todayOrders - 100 : 0)
                    .ordersGrowth(ordersGrowth)
                    .conversionRate(conversionRate != null ? conversionRate : BigDecimal.ZERO)
                    .conversionChange(growthRates != null ? (BigDecimal) growthRates.get("conversionChange") : BigDecimal.ZERO)
                    .avgConversionRate(BigDecimal.valueOf(3.68))
                    .build();
        } catch (Exception e) {
            log.error("获取KPI指标失败", e);
            return createMockKPIMetrics();
        }
    }

    @Override
    public DetailMetricsVO getDetailMetrics(DateRangeQuery queryParams) {
        try {
            String timePeriod = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
            
            // 获取访客数据
            Map<String, Object> visitorData = productSalesMapper.getVisitorData(timePeriod);
            
            // 获取成交数据
            Map<String, Object> transactionData = productSalesMapper.getTransactionData(timePeriod);
            
            // 获取商品浏览数据
            Map<String, Object> productViewStats = productSalesMapper.getProductViewStats(timePeriod);
            
            // 获取店铺关注数据
            List<Map<String, Object>> storeFollowData = productSalesMapper.getStoreFollowData(timePeriod);
            
            // 安全地获取数值，避免空指针异常
            Integer totalVisitors = 0;
            if (visitorData != null && visitorData.get("totalVisitors") != null) {
                totalVisitors = ((Number) visitorData.get("totalVisitors")).intValue();
            }
            
            Integer totalBuyers = 0;
            if (transactionData != null && transactionData.get("totalBuyers") != null) {
                totalBuyers = ((Number) transactionData.get("totalBuyers")).intValue();
            }
            
            Integer totalPageViews = 0;
            if (productViewStats != null && productViewStats.get("totalPageViews") != null) {
                totalPageViews = ((Number) productViewStats.get("totalPageViews")).intValue();
            }
            
            Integer storeFollowers = 0;
            if (storeFollowData != null && !storeFollowData.isEmpty()) {
                storeFollowers = storeFollowData.stream()
                    .filter(data -> data.get("followers") != null)
                    .mapToInt(data -> ((Number) data.get("followers")).intValue())
                    .sum();
            }
            
            BigDecimal unitPrice = BigDecimal.ZERO;
            if (transactionData != null && transactionData.get("avgTransactionValue") != null) {
                unitPrice = (BigDecimal) transactionData.get("avgTransactionValue");
            }
            
            return DetailMetricsVO.builder()
                    .unitPrice(unitPrice)
                    .unitPriceGrowth(BigDecimal.valueOf(5.2))
                    .visitors(totalVisitors)
                    .visitorsGrowth(BigDecimal.valueOf(12.3))
                    .buyers(totalBuyers)
                    .buyersGrowth(BigDecimal.valueOf(8.7))
                    .productViews(BigDecimal.valueOf(totalPageViews / 1000.0))
                    .productViewsGrowth(BigDecimal.valueOf(15.6))
                    .storeFollows(storeFollowers)
                    .storeFollowsGrowth(BigDecimal.valueOf(9.4))
                    .refundRate(BigDecimal.valueOf(2.8))
                    .refundRateChange(BigDecimal.valueOf(-0.5))
                    .build();
        } catch (Exception e) {
            log.error("获取详细指标失败", e);
            return createMockDetailMetrics();
        }
    }

    @Override
    public SalesTrendResponseVO getSalesTrend(DateRangeQuery queryParams) {
        try {
            LocalDate startDate = queryParams != null ? queryParams.getStartDate() : LocalDate.now().minusDays(7);
            LocalDate endDate = queryParams != null ? queryParams.getEndDate() : LocalDate.now();
            
            List<Map<String, Object>> trendData = dailySalesReportMapper.getSalesTrendData(startDate, endDate);
            
            if (CollectionUtils.isEmpty(trendData)) {
                return createMockSalesTrend(startDate, endDate);
            }
            
            List<SalesTrendResponseVO.SalesTrendPointVO> dataPoints = new ArrayList<>();
            BigDecimal totalGMV = BigDecimal.ZERO;
            Integer totalOrders = 0;
            
            for (Map<String, Object> data : trendData) {
                LocalDate date = (LocalDate) data.get("date");
                BigDecimal gmv = (BigDecimal) data.get("gmv");
                Integer orders = ((Number) data.get("orders")).intValue();
                
                totalGMV = totalGMV.add(gmv != null ? gmv : BigDecimal.ZERO);
                totalOrders += orders != null ? orders : 0;
                
                dataPoints.add(SalesTrendResponseVO.SalesTrendPointVO.builder()
                        .date(date.format(DATE_FORMATTER))
                        .gmv(gmv != null ? gmv : BigDecimal.ZERO)
                        .orders(orders != null ? orders : 0)
                        .build());
            }
            
            SalesTrendResponseVO.SummaryVO summary = SalesTrendResponseVO.SummaryVO.builder()
                    .totalGMV(totalGMV)
                    .totalOrders(totalOrders)
                    .avgGMV(dataPoints.size() > 0 ? totalGMV.divide(BigDecimal.valueOf(dataPoints.size()), 2, RoundingMode.HALF_UP) : BigDecimal.ZERO)
                    .avgOrders(dataPoints.size() > 0 ? totalOrders / dataPoints.size() : 0)
                    .build();
            
            return SalesTrendResponseVO.builder()
                    .data(dataPoints)
                    .summary(summary)
                    .build();
        } catch (Exception e) {
            log.error("获取销售趋势失败", e);
            return createMockSalesTrend(queryParams != null ? queryParams.getStartDate() : LocalDate.now().minusDays(7),
                                      queryParams != null ? queryParams.getEndDate() : LocalDate.now());
        }
    }

    @Override
    public CategorySalesResponseVO getCategorySales(DateRangeQuery queryParams) {
        try {
            String timePeriod = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
            
            List<Map<String, Object>> categoryData = productSalesMapper.getCategorySalesData(timePeriod);
            
            List<CategorySalesResponseVO.CategorySalesDataVO> dataList = new ArrayList<>();
            BigDecimal totalAmount = BigDecimal.ZERO;
            
            if (!CollectionUtils.isEmpty(categoryData)) {
                String[] colors = {"#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#FFEAA7", "#DDA0DD"};
                
                for (int i = 0; i < categoryData.size(); i++) {
                    Map<String, Object> data = categoryData.get(i);
                    String name = (String) data.get("name");
                    BigDecimal amount = (BigDecimal) data.get("amount");
                    BigDecimal percentage = (BigDecimal) data.get("percentage");
                    
                    totalAmount = totalAmount.add(amount != null ? amount : BigDecimal.ZERO);
                    
                    dataList.add(CategorySalesResponseVO.CategorySalesDataVO.builder()
                            .name(name)
                            .percentage(percentage != null ? percentage : BigDecimal.ZERO)
                            .amount(amount != null ? amount : BigDecimal.ZERO)
                            .color(colors[i % colors.length])
                            .build());
                }
            }
            
            CategorySalesResponseVO.SummaryVO summary = CategorySalesResponseVO.SummaryVO.builder()
                    .totalAmount(totalAmount)
                    .categoryCount(dataList.size())
                    .topCategory(dataList.isEmpty() ? "暂无数据" : dataList.get(0).getName())
                    .build();
            
            return CategorySalesResponseVO.builder()
                    .data(dataList)
                    .summary(summary)
                    .build();
        } catch (Exception e) {
            log.error("获取品类销售失败", e);
            // 异常时也返回空数据，不使用模拟数据
            return CategorySalesResponseVO.builder()
                    .data(new ArrayList<>())
                    .summary(CategorySalesResponseVO.SummaryVO.builder()
                            .totalAmount(BigDecimal.ZERO)
                            .categoryCount(0)
                            .topCategory("暂无数据")
                            .build())
                    .build();
        }
    }

    @Override
    public DashboardAllDataVO getAllData(DateRangeQuery queryParams) {
        return DashboardAllDataVO.builder()
                .headerInfo(getHeaderInfo())
                .kpiMetrics(getKPIMetrics(queryParams))
                .detailMetrics(getDetailMetrics(queryParams))
                .salesTrend(getSalesTrend(queryParams))
                .categorySales(getCategorySales(queryParams))
                .build();
    }

    @Override
    public RealTimeDataVO refreshRealTimeData() {
        return RealTimeDataVO.builder()
                .onlineUsers(generateOnlineUsers())
                .todayGMV(BigDecimal.valueOf(158000.00))
                .todayOrders(342)
                .realtimeVisitors(1256)
                .currentConversionRate(BigDecimal.valueOf(3.8))
                .lastUpdateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm")))
                .refreshStatus("success")
                .build();
    }

    // 私有方法：模拟数据创建
    private DashboardHeaderInfoVO createMockHeaderInfo() {
        return DashboardHeaderInfoVO.builder()
                .onlineUsers(generateOnlineUsers())
                .onlineGrowth(BigDecimal.valueOf(8.5))
                .salesProgress(BigDecimal.valueOf(68.2))
                .storeCount(5)
                .storeStatus("open")
                .build();
    }

    private KPIMetricsVO createMockKPIMetrics() {
        return KPIMetricsVO.builder()
                .todayGMV(BigDecimal.valueOf(158000.00))
                .gmvGrowth(BigDecimal.valueOf(15.8))
                .targetAchievement(BigDecimal.valueOf(78.5))
                .targetGrowth(BigDecimal.valueOf(12.8))
                .monthlyTarget(BigDecimal.valueOf(2000000.00))
                .todayOrders(342)
                .yesterdayOrders(280)
                .ordersGrowth(BigDecimal.valueOf(18.2))
                .conversionRate(BigDecimal.valueOf(3.8))
                .conversionChange(BigDecimal.valueOf(0.5))
                .avgConversionRate(BigDecimal.valueOf(3.68))
                .build();
    }

    private DetailMetricsVO createMockDetailMetrics() {
        return DetailMetricsVO.builder()
                .unitPrice(BigDecimal.valueOf(462.05))
                .unitPriceGrowth(BigDecimal.valueOf(5.2))
                .visitors(12580)
                .visitorsGrowth(BigDecimal.valueOf(12.3))
                .buyers(478)
                .buyersGrowth(BigDecimal.valueOf(8.7))
                .productViews(BigDecimal.valueOf(25.6))
                .productViewsGrowth(BigDecimal.valueOf(15.6))
                .storeFollows(3200)
                .storeFollowsGrowth(BigDecimal.valueOf(9.4))
                .refundRate(BigDecimal.valueOf(2.8))
                .refundRateChange(BigDecimal.valueOf(-0.5))
                .build();
    }

    private SalesTrendResponseVO createMockSalesTrend(LocalDate startDate, LocalDate endDate) {
        List<SalesTrendResponseVO.SalesTrendPointVO> dataPoints = new ArrayList<>();
        BigDecimal totalGMV = BigDecimal.ZERO;
        Integer totalOrders = 0;
        
        LocalDate current = startDate;
        while (!current.isAfter(endDate)) {
            BigDecimal gmv = BigDecimal.valueOf(120000 + random.nextInt(80000));
            Integer orders = 250 + random.nextInt(200);
            
            totalGMV = totalGMV.add(gmv);
            totalOrders += orders;
            
            dataPoints.add(SalesTrendResponseVO.SalesTrendPointVO.builder()
                    .date(current.format(DATE_FORMATTER))
                    .gmv(gmv)
                    .orders(orders)
                    .build());
            
            current = current.plusDays(1);
        }
        
        SalesTrendResponseVO.SummaryVO summary = SalesTrendResponseVO.SummaryVO.builder()
                .totalGMV(totalGMV)
                .totalOrders(totalOrders)
                .avgGMV(dataPoints.size() > 0 ? totalGMV.divide(BigDecimal.valueOf(dataPoints.size()), 2, RoundingMode.HALF_UP) : BigDecimal.ZERO)
                .avgOrders(dataPoints.size() > 0 ? totalOrders / dataPoints.size() : 0)
                .build();
        
        return SalesTrendResponseVO.builder()
                .data(dataPoints)
                .summary(summary)
                .build();
    }

    private Integer generateOnlineUsers() {
        LocalDateTime now = LocalDateTime.now();
        int hour = now.getHour();
        
        // 根据时间模拟在线用户数变化
        int baseUsers = 800;
        if (hour >= 9 && hour <= 11) baseUsers = 1200; // 上午高峰
        else if (hour >= 14 && hour <= 16) baseUsers = 1400; // 下午高峰
        else if (hour >= 19 && hour <= 22) baseUsers = 1600; // 晚上高峰
        else if (hour >= 0 && hour <= 6) baseUsers = 300; // 深夜低谷
        
        return baseUsers + random.nextInt(200);
    }
} 